abstract class BaseClass {
    constructor() { }

    //模板方法
    public template(): void {
        this.operation1()
        this.hook() && this.operation2()
        this.operation3()
    }

    //基本方法
    protected operation1(): void {
        console.log("do operation1");
    }

    protected operation2(): void {
        console.log("do operation2");
    }

    protected operation3(): void {
        console.log("do operation3");
    }

    //钩子方法
    protected hook(): boolean {
        return true
    }
}

class SpecificClassA extends BaseClass {
    protected operation1(): void {
        console.log("重写了的operation1");
    }

    protected operation2(): void {
        console.log("重写了的operation2");
    }


    protected operation3(): void {
        console.log("重写了的operation3");
    }
}

class SpecificClassB extends BaseClass {
    //重写钩子方法，使operation2不会执行
    protected hook(): boolean {
        return false
    }
}

const TemplateTest = (): void => {
    const specificClassA : SpecificClassA = new SpecificClassA()
    const specificClassB : SpecificClassB = new SpecificClassB()

    //执行重写了的operation1、operation2、operation3
    specificClassA.template()

    //执行operation1、operation3
    specificClassB.template()
}

TemplateTest()